/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package tools;

import com.openbrew.openbrewrf.BarrelConditioning;
import com.openbrew.openbrewrf.Barrels;
import com.openbrew.openbrewrf.Employee;
import com.openbrew.openbrewrf.Movement;
import com.openbrew.openbrewrf.views.BrewView;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import service.enumerations.MovementState;
import service.miscListModels.BarrelList;

/**
 *
 * @author dchapman
 */
public class BarrelTools {
    /***************************************************************************
     * Do Movement To Barrel
     * @param en
     * @param barrelID
     * @param brewID
     * @param employeeID
     * @param volume
     * @param moveDate
     * @return 
     **************************************************************************/
    public Barrels doMovementTobarrel(final EntityManager en, final int barrelID
            , final int brewID, final int employeeID, final float volume, final Date moveDate){
        final BrewView batch = getBrewViewFromID(en, brewID);
        final Barrels barrel = getBarrelFromID(en, barrelID);
        final Employee employee = getEmployeeFromID(en, employeeID);
        final MovementState movementState = MovementState.getState(batch.getbState());
        final int oldVesselID = getOldVesselID(movementState, batch);
        
        if(volume<=barrel.getBarVol()){
            //Update the new volume in the tank.
            double newVol = (double)batch.getVolLeft() - (double)volume;
            if (newVol < 0) {
                    newVol = 0;
            }
            
            //Create Movement
            Movement mvmt = new Movement();
            mvmt.setMovementDate(moveDate);
            mvmt.setMovementBrewID(brewID);
            mvmt.setMovementOldState(batch.getbState());
            mvmt.setMovementStateID(MovementState.BARREL_CONDITIONING.getState());
            mvmt.setMovementVolume(volume);
            mvmt.setMovementEmpID(employeeID);
            mvmt.setMovementNotes("Barrel ageing movement added by openBrew");
            mvmt.setMovementOVID(oldVesselID);
            mvmt.setMovementNVID(0);
            en.persist(mvmt);
            
            //Update Brew Accordingly.
            if (newVol <= 1.90) {
                batch.setVolLeft(0);
                batch.setbState(25);
            } else {
                batch.setVolLeft((float)newVol);
            }
            BrewsTools bt = new BrewsTools();
            bt.doUpdateAndCheckForRefactor(en, batch);
            
            //Now update barrel database.
            barrel.setCurrentBatch(batch);
            barrel.setCurrentVol(volume);
            barrel.setDateFilled(moveDate);
            en.merge(barrel);
        }
        return barrel;
    }
    
    private int getOldVesselID(MovementState state, BrewView batch){
        int oldVesselID = 0;
        switch (state) {
        case BREWING:
                break;
        case FERMENTING:
                oldVesselID = batch.getPfvid();
                break;
        case LAGERING:
                oldVesselID = batch.getSfvid();
                break;
        case CONDITIONING:
                oldVesselID = batch.getCvid();
                break;
        case KEGGED:
                break;
        case BOTTLED:
                break;
        case BARREL_CONDITIONING:
                break;
        }
        return oldVesselID;
    }

    /*************************************************************************
     * Move Barrels to Vessel
     *
     * @param en
     * @param moveDate
     * @param newVesselID
     * @param barrelList
     * @param employeeID
     ************************************************************************/
    public void moveBarrelsToVessel(final EntityManager en, final Date moveDate, final int newVesselID
            , final BarrelList barrelList, final int employeeID) {
        final DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        float totalVolume = 0; //used to fill out barrelconditioningtable.
        String batchCSV = ""; //used to fill out batches in final product.

        if(barrelList.getBarrels()!=null && moveDate!=null){
            for (final Barrels barrel : barrelList.getBarrels()) {
                submitMovement(en, barrel.getCurrentBatch().getBid(), moveDate, barrel.getCurrentVol(), newVesselID, Integer.toString(barrel.getBarID()),
                        employeeID);
                //Update Barrel data at this point. set volume 0, batch 0, date to 0001-01-01
                //Also, append the batch number and date to the history.
                totalVolume += barrel.getCurrentVol();
                batchCSV += Integer.toString(barrel.getCurrentBatch().getBid()) + ",";

                String history = barrel.getPastBatches();
                history += Integer.toString(barrel.getCurrentBatch().getBid()) + " on "
                        + barrel.getDateFilled().toString() + ",";
                barrel.setPastBatches(history);
                barrel.setCurrentVol(0);
                barrel.setCurrentBatch(null);
                String date = "0001-01-01";
                try {
                    final java.util.Date rstDate = formatter.parse(date);
                    barrel.setDateFilled(rstDate);
                } catch (ParseException e) {

                }
                en.merge(barrel);
            }

            // trim last comma off of batchCSV
            final String newCSV = batchCSV.substring(0, batchCSV.length() - 1);

            BarrelConditioning bc = new BarrelConditioning();
            bc.setBCOrigVol(totalVolume);
            bc.setBCVolLeft(totalVolume);
            bc.setBCPackaged(false);
            bc.setBCBatches(newCSV);
            bc.setBCVesselID(newVesselID);
            bc.setBCDatePkg(moveDate);
            bc.setBCFillDate(moveDate);
            en.persist(bc);
        }
    }

    private void submitMovement(final EntityManager en, final int brewID, final Date moveDate,
            final float totalVol, final int newVessel, final String beerNote, final int employeeID) {
        Movement mvmt = new Movement();
        mvmt.setMovementDate(moveDate);
        mvmt.setMovementBrewID(brewID);
        mvmt.setMovementOldState(MovementState.BARREL_CONDITIONING.getState());
        mvmt.setMovementStateID(MovementState.BARREL_FOR_PACKAGING.getState());
        mvmt.setMovementVolume(totalVol);
        mvmt.setMovementEmpID(employeeID);
        mvmt.setMovementNotes("Barrel " + beerNote + " moved into conditioning by openBrew");
        mvmt.setMovementOVID(0);
        mvmt.setMovementNVID(newVessel);
        en.persist(mvmt);
    }
    
    /***************************************************************************
     * Database Access functions.
     **************************************************************************/
    private Barrels getBarrelFromID(final EntityManager en, final int barrelID){
        TypedQuery<Barrels> query = en.createQuery(
                "SELECT b FROM Barrels b WHERE b.barID = ?1", Barrels.class);
        query.setParameter(1, barrelID);
        return query.getSingleResult();
    }
    
    private BrewView getBrewViewFromID(final EntityManager en, final int brewID){
        TypedQuery<BrewView> query = en.createQuery(
                "SELECT b FROM BrewView b WHERE b.bid = ?1", BrewView.class);
        query.setParameter(1, brewID);
        return query.getSingleResult();
    }
    
    private Employee getEmployeeFromID(final EntityManager en, final int employeeID){
        TypedQuery<Employee> query = en.createQuery(
                "SELECT e FROM Employee e WHERE e.empID = ?1", Employee.class);
        query.setParameter(1, employeeID);
        return query.getSingleResult();
    }
}
